package com.dc.chat.app.biz.impl;

import com.dc.chat.app.biz.UserBiz;
import com.dc.chat.app.service.FileService;
import com.dc.chat.app.service.mp.FriendService;
import com.dc.chat.app.service.mp.UserService;
import com.dc.chat.entity.dao.User;
import com.dc.chat.entity.redisCatch.LoginUser;
import com.dc.chat.entity.to.ResponseBean;
import com.dc.chat.entity.to.user.GetInfoResp;
import com.dc.chat.entity.to.user.SearchUserResp;
import com.dc.chat.interceptor.security.SecurityInterceptor;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class UserBizImpl implements UserBiz {
    @Autowired
    UserService userService;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    FileService fileService;
    @Override
    public ResponseBean<Integer> register(String username, String password) {
        User user=userService.selectByUserName(username);
        if(user!=null){
            return ResponseBean.failed("该账号已被注册");
        }
        user=new User();
        user.setUserName(username);
        user.setPassword(password);
        user.setNickName(username);
        user.setAvatar("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202106%2F13%2F20210613235426_7a793.thumb.1000_0.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1679791240&t=9f8085d5d06b4c5ee7c4b201168277d5");
        user.setStatus(0);
        user.setDeleted(0);
        userService.save(user);
        Set<String> adminTokens = redisTemplate.opsForSet().members("admin");
        //告诉所有管理员 重新获取列表
        Map map=new HashMap();
        map.put("refresh",true);
        for (String adminToken : adminTokens) {
            simpMessagingTemplate.convertAndSend("/back/"+adminToken,"",map);
        }
        return ResponseBean.success("注册成功",user.getId());
    }

    @Override
    public ResponseBean<String> login(String username, String password) {
        User user=userService.selectByUserNameAndPassword(username,password);
        if(user==null){
            return ResponseBean.failed("用户名或密码错误");
        }
        Integer status = user.getStatus();
        if(status.equals(1)){
            return ResponseBean.failed("账号已被禁用，请联系管理员");
        }

        String uuid= UUID.randomUUID().toString();
//        https://www.jianshu.com/p/188254545332
        JwtBuilder jwtBuilder = Jwts.builder()
                .claim("uuid", uuid)
                .claim("username", username)
                .signWith(SignatureAlgorithm.HS512, "abcdef");
        String compact = jwtBuilder.compact();
        //redis
        //只允许有一个带连接websocket
        Set keys = redisTemplate.keys("login.0." + username + ".*");
        keys.forEach(key->{
            redisTemplate.delete(key);
        });
        //设置待登录
        String key="login#0#"+username+"#"+compact;
        LoginUser value=new LoginUser();
        value.setId(user.getId());
        value.setUsername(user.getUserName());
        value.setAvatar(user.getAvatar());
        value.setNickname(user.getNickName());
        //认证成功后 60分钟内可以连websocket 只要没人再次用此账号认证
        redisTemplate.opsForValue().set(key,value);
        return ResponseBean.success("认证成功",compact);
    }

    @Override
    public ResponseBean<GetInfoResp> getInfo() {
        String userName = SecurityInterceptor.threadLocal.get();
        User user = userService.selectByUserName(userName);
        GetInfoResp getInfoResp = new GetInfoResp();
        getInfoResp.setId(user.getId());
        getInfoResp.setUsername(user.getUserName());
        getInfoResp.setNickname(user.getNickName());
        getInfoResp.setAvatar(user.getAvatar());
        return ResponseBean.success("查询成功",getInfoResp);
    }

    @Override
    public ResponseBean<SearchUserResp> searchUser(String username) {
        String s = SecurityInterceptor.threadLocal.get();
        if(s.equals(username)){
            return ResponseBean.failed("不能添加自己为好友");
        }
        //TODO 查看是不是已经是好友了
        User user = userService.selectByUserName(username);
        if(user==null){
            return ResponseBean.failed("找不到该用户");
        }
        SearchUserResp searchUserResp=new SearchUserResp();
        searchUserResp.setId(user.getId());
        searchUserResp.setUsername(user.getUserName());
        searchUserResp.setNickname(user.getNickName());
        searchUserResp.setAvatar(user.getAvatar());
        return ResponseBean.success("查询成功",searchUserResp);
    }

    @Override
    public ResponseBean editNickname(String nickname) {
        String s = SecurityInterceptor.threadLocal.get();
        User user = userService.selectByUserName(s);
        user.setNickName(nickname);
        userService.updateById(user);
        //websocket 通知在线好于 修改头像了
        Collection<String> friendsUsername = friendService.getFriendsUsername(user.getUserName());
        Map login = redisTemplate.opsForHash().entries("login");
        for (String frinendUsername : friendsUsername) {
            String friendToken = (String) login.get(frinendUsername);
            if(friendToken!=null){
                Map map=new HashMap();
                map.put("friendChangeNickname",true);
                map.put("username",user.getUserName());
                simpMessagingTemplate.convertAndSend("/u/"+friendToken,nickname,map);
            }
        }
        //告诉所有管理员 重新获取列表
        Set<String> adminTokens = redisTemplate.opsForSet().members("admin");
        Map map=new HashMap();
        map.put("refresh",true);
        for (String adminToken : adminTokens) {
            simpMessagingTemplate.convertAndSend("/back/"+adminToken,"",map);
        }
        return ResponseBean.success("",null);
    }
@Resource
FriendService friendService;
    @Resource
    SimpMessagingTemplate simpMessagingTemplate;
    @Override
    public ResponseBean changeAvatar(MultipartFile file) throws IOException {
        ResponseBean<String> upload = fileService.upload(file);
        String data = upload.getData();
        String username=SecurityInterceptor.threadLocal.get();
        User user = userService.selectByUserName(username);
        user.setAvatar(data);
        userService.updateById(user);
        Set keys = redisTemplate.keys("login#1#" + username + "#*");
        keys.forEach(i->{
            LoginUser loginUser = (LoginUser) redisTemplate.opsForValue().get(i);
            loginUser.setAvatar(data);
            redisTemplate.opsForValue().set(i,loginUser);
        });
        //websocket 通知在线好于 修改头像了
        Collection<String> friendsUsername = friendService.getFriendsUsername(username);
        Map login = redisTemplate.opsForHash().entries("login");
        for (String frinendUsername : friendsUsername) {
            String friendToken = (String) login.get(frinendUsername);
            if(friendToken!=null){
                Map map=new HashMap();
                map.put("friendChangeAvatar",true);
                map.put("username",username);
                simpMessagingTemplate.convertAndSend("/u/"+friendToken,data,map);
            }

        }
        //告诉所有管理员 重新获取列表
        Set<String> adminTokens = redisTemplate.opsForSet().members("admin");
        Map map=new HashMap();
        map.put("refresh",true);
        for (String adminToken : adminTokens) {
            simpMessagingTemplate.convertAndSend("/back/"+adminToken,"",map);
        }
        return ResponseBean.success("",null);
    }
}
